package com.it.travel.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.it.travel.common.ConstEnum;
import com.it.travel.dao.PermissionMapper;
import com.it.travel.dao.RoleMapper;
import com.it.travel.dao.UserMapper;
import com.it.travel.dao.UserRoleMapper;
import com.it.travel.dto.PermissionDTO;
import com.it.travel.pojo.Permission;
import com.it.travel.pojo.Role;
import com.it.travel.pojo.User;
import com.it.travel.pojo.UserRole;
import com.it.travel.service.EmailService;
import com.it.travel.service.UserService;
import com.it.travel.vo.Params.LoginParams;
import com.it.travel.vo.Params.RegisterParams;
import com.it.travel.vo.Result;
import lombok.SneakyThrows;
import org.apache.tomcat.util.bcel.Const;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.util.*;

@Service
@EnableAsync//开启异步调用
public class UserServiceImpl implements UserService {
    @Autowired
    JavaMailSenderImpl mailSender;
    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private PermissionMapper permissionMapper;
    @Autowired
    private EmailService emailService;

    List<Permission> getPermission(List<Permission> allList, Integer pid) {
        List<Permission> list = new ArrayList<>();
        for (Permission permission : allList) {
            if (pid == 0) {  // 一级权限
                list.add(permission);
                List<Permission> permission2 = getPermission(allList, permission.getId());
                permission.setChildren(permission2);

            } else if (pid.equals(permission.getParentId())) {
                list.add(permission);

                List<Permission> permission2 = getPermission(allList, permission.getId());
                permission.setChildren(permission2);
            }
        }
        return list;
    }


    @Override
    public Result<?> login(LoginParams loginParams) {
        String username = loginParams.getUsername();
        String password = loginParams.getPassword();
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return Result.error(null, "账号或密码不能为空");
        }
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(User::getUsername, username);
        User user = userMapper.selectOne(wrapper);
        if (user == null) {
            return Result.error(null, "该账户不存在");
        }
        String md5Password = SecureUtil.md5(user.getSalt() + password); // 加密处理

        if (user.getIsActive().equals(ConstEnum.IS_NOTACTIVE.getNum())) {
            return Result.error(null, "账号还未激活，请登录邮箱进行激活");
        }
        System.out.println("md5Password = " + md5Password);
        if (!user.getPassword().equals(md5Password)) {
            return Result.error(null, "密码不正确");
        }
//        8c21ba08038506339e88aeeb52f81394
        // 密钥
//        jwt的生成
//        HashMap<String, Object> map = new HashMap<>();
//        List<Permission> permissions = permissionMapper.selectList(null);
//        PermissionDTO jzs = userMapper.queryPermissionIdByParentIdAndUserName("jzs");
//        List<Integer> permissionIdList = jzs.getPermissionId();
//        List<Permission> list = new ArrayList<>();
//        List<Permission> permission = getPermission(permissions, 0);
//        for (Permission permission1 : permission) {  // 得到用户所对应的树形权限数据
//            if (permission1.getParentId() == 0) {  // 得到一级
//                for (Integer integer : permissionIdList) {
//                    if (integer.equals(permission1.getId())) {
//                        list.add(permission1);
//                    }
//                }
//            }
//        }
        HashMap<String, Object> map = new HashMap<>();
//        这里不应该查询所有 ，因为，应该为角色分配权限，这样查出来的还是所有的数据
//        List<Permission> permissions = permissionMapper.selectList(null);
//        查出角色的id
        UserRole userRole = userRoleMapper.selectOne(new QueryWrapper<UserRole>().eq("user_id", user.getId()));
        Integer roleId = userRole.getRoleId();
        List<Permission> permissions = userMapper.queryPermissionListByRoleId(roleId); // 根据角色的id查出对应的所有的权限
        List<PermissionDTO> permissionDTOS = userMapper.queryPermissionIdByParentIdAndUserName(loginParams.getUsername());
        List<Integer> permissionIdList = new ArrayList<>();
        for (PermissionDTO jz : permissionDTOS) {  // 将对象中的permissionid赋给一个新数组
            permissionIdList.add(jz.getPermissionId());
        }
        List<Permission> list = new ArrayList<>();
        List<Permission> permission = getPermission(permissions, 0);
        for (Permission permission1 : permission) {  // 得到用户所对应的树形权限数据
            if (permission1.getParentId() == 0) {  // 得到一级
                for (Integer integer : permissionIdList) {
                    if (integer.equals(permission1.getId())) {
                        list.add(permission1);
                    }
                }
            }
        }
        String s = userMapper.queryRoleNameByUserName(loginParams.getUsername()); // 查询到的角色名
//         认证以后，根据用户名查询当前认证用户的角色信息，在对应其权限信息
        byte[] key = ConstEnum.JWT_SALT.getStr().getBytes();
        String token = JWT.create()
//                .setPayload("nickname", user.getNickname())
                .setPayload("id", user.getId())
                .setPayload("realname", user.getRealname()) // 真实姓名
                .setPayload("username", user.getUsername())
                .setPayload("isActive", user.getIsActive()) // 激活的状态
                .setKey(key).setExpiresAt(new Date(System.currentTimeMillis() + 1000 * 10))  // 10分钟过期
                .sign();
        System.out.println("list = " + list);
        System.out.println("token = " + token);
        map.put("permissionList", list);
        map.put("token", token);
        map.put("roleName", s);
        return Result.success(map, "登录成功");
    }

    @Override
    public Result<?> register(RegisterParams registerParams) throws MessagingException {
        String email = registerParams.getEmail();
        String nickname = registerParams.getNickname();
        String password = registerParams.getPassword();
        String realname = registerParams.getRealname();
        String username = registerParams.getUsername();
        if (StringUtils.isBlank(email) || StringUtils.isBlank(nickname) || StringUtils.isBlank(password) ||
                StringUtils.isBlank(realname) || StringUtils.isBlank(username)
        ) {
            return Result.error(null, "请检查，不能为空");
        }
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
        LambdaQueryWrapper<User> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(User::getEmail, email);
        wrapper.eq(User::getUsername, username);
        User user1 = userMapper.selectOne(wrapper1);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            return Result.error(null, "该用户名已被注册");
        }
        if (user1 != null) {
            return Result.error(null, "该邮箱已被注册，请重试");
        }
        User registerUser = new User();
        BeanUtil.copyProperties(registerParams, registerUser);
        registerUser.setCreateTime(System.currentTimeMillis());
        registerUser.setUpdateTime(System.currentTimeMillis());
        String salt = UUID.randomUUID().toString().substring(10);
        registerUser.setSalt(salt);// 使用UUID作为盐
        String md5 = SecureUtil.md5(salt + registerUser.getPassword());
        registerUser.setPassword(md5);// 密码 盐+原始密码
        int insert = userMapper.insert(registerUser);
        //        复杂邮件的发送
        emailService.sendEmail(registerParams);   // 因为使用优雅的async注解，要在不同的类当中
        if (insert > 0) {
            Integer id = registerUser.getId();  // 进行用户角色表的维护，默认角色为游客
            Role role = roleMapper.selectOne(new QueryWrapper<Role>().eq("role_name", "游客"));// 先查出角色对应的id，根据角色名来查
            if (role != null) {
                Integer roleId = role.getId();
                UserRole userRole = new UserRole();
                userRole.setRoleId(roleId);
                userRole.setUserId(id);
                userRoleMapper.insert(userRole);
            }

            return Result.success(null, "注册成功");
        }
        return Result.error(null, "注册失败");
    }


    @Override
    public Result<?> active(String code) {
        if (StringUtils.isNotBlank(code)) {
            LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(User::getUsername, code);
            User user = userMapper.selectOne(wrapper);
            if (user != null) {
                LambdaQueryWrapper<User> wrapper1 = Wrappers.lambdaQuery();
//                    wrapper1.u
                user.setIsActive(ConstEnum.IS_ACTIVE.getNum());
                int i = userMapper.updateById(user);
                if (i > 0) {
                    return Result.success(null, "激活成功");
                }
                return Result.error(null, "激活失败");
            }
        }
//            userMapper.sele
        return null;
    }
}
